﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ReadCSV
{
   
    public class DanhSachDoiTuong
    {
        List<string> _TenThuocTinh;

        List<string> _LoaiThuocTinh;

        List<List<string>> _list;

        List<string> _GiaTriDaiDien;

        List<int> _SoMauPhanBiet;

        List<int> _SoMauThieu;

        List<List<string>> _GiaTriPhanBiet;

        List<string> _Min;

        List<string> _Max;

        int _SoThuocTinh;

        int _SoLuongMau;

        public List<string> TenThuocTinh
        {
            get { return _TenThuocTinh; }
            set { _TenThuocTinh = value; }
        }
        public List<string> LoaiThuocTinh
        {
            get { return _LoaiThuocTinh; }
            set { _LoaiThuocTinh = value; }
        }

        public List<List<string>> List
        {
            get { return _list; }
            set { _list = value; }
        }

        public List<string> GiaTriDaiDien
        {
            get { return _GiaTriDaiDien; }
            set { _GiaTriDaiDien = value; }
        }

        public int nThuocTinh
        {
            get { return _SoThuocTinh; }
            set { _SoThuocTinh = value; }
        }

        public int nMau
        {
            get { return _SoLuongMau; }
            set { _SoLuongMau = value; }
        }

        public DanhSachDoiTuong()
        {
            _TenThuocTinh = new List<string>();
            _LoaiThuocTinh = new List<string>();
            _list = new List<List<string>>();
            _GiaTriDaiDien = new List<string>();
        }

        public DanhSachDoiTuong(string url)
        {
            ReadCSV(url);
        }

        public List<int> SoMauPhanBiet
        {
            get { return _SoMauPhanBiet; }
            set { _SoMauPhanBiet = value; }
        }

        public List<int> SoMauThieu
        {
            get { return _SoMauThieu; }
            set { _SoMauThieu = value; }
        }

        public List<List<string>> GiatriPhanBiet
        {
            get { return _GiaTriPhanBiet; }
            set { _GiaTriPhanBiet = value; }
        }

        public List<string> Min
        {
            get { return _Min; }
            set { _Min = value; }
        }

        public List<string> Max
        {
            get { return _Max; }
            set { _Max = value; }
        }

        void Read_Data(string url)
        {
            _list = new List<List<string>>();
            var reader = new StreamReader(File.OpenRead(url));
            var line = reader.ReadLine();
            while (!reader.EndOfStream)
            {
                line = reader.ReadLine();
                try
                {
                    var values = line.Split(',');
                    var listtemp = new List<String>();
                    for (int i = 0; i < values.Length; i++)
                        listtemp.Add(values[i]);                    
                    _list.Add(listtemp);
                }
                catch (Exception ex)
                {
                    var values = line.Split(';');
                    var listtemp = new List<String>();
                    for (int i = 0; i < values.Length; i++)
                        listtemp.Add(values[i]);                    
                    _list.Add(listtemp);
                }
            }
            _SoLuongMau = _list.Count;
        }

        string KiemTraLoai(string str)
        {
            string temp = null;
            try
            {
                Convert.ToDouble(str);
                temp = "numeric";
            }
            catch (FormatException ex)
            {
                temp = "nominal";
            }
            return temp;
        }
        void Set_LoaiThuocTinh(string[] temp)
        {
            for (int i = 0; i < temp.Length; i++)
            {
                LoaiThuocTinh.Add(KiemTraLoai(temp[i]));
            }
        }

        void Read_LoaiThuocTinh(string url)
        {
            _LoaiThuocTinh = new List<string>();
            var reader = new StreamReader(File.OpenRead(url));
            var line = reader.ReadLine();
            line = reader.ReadLine();
            try
            {
                var values = line.Split(',');
                Set_LoaiThuocTinh(values);
            }
            catch (Exception ex)
            {
                var values = line.Split(';');
                Set_LoaiThuocTinh(values);
            }
        }

        void Read_ThuocTinh(string url)
        {
            _TenThuocTinh = new List<string>();
            var reader = new StreamReader(File.OpenRead(url));
            var line = reader.ReadLine();
            try
            {
                var values = line.Split(',');
                for (int i = 0; i < values.Length; i++)
                    TenThuocTinh.Add(values[i]);
            }
            catch (Exception ex)
            {
                var values = line.Split(';');
                for (int i = 0; i < values.Length; i++)
                    TenThuocTinh.Add(values[i]);
            }
            _SoThuocTinh = _TenThuocTinh.Count;
        }

        int TanSuat(int vt, string gt)
        {
            int dem = 0;
            for (int i = 0; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] == gt)
                    dem++;
            }
            return dem;
        }
        int TanSuat(int bd, int vt, string gt)
        {
            int dem = 0;
            for (int i = bd; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] == gt)
                    dem++;
            }
            return dem;
        }
        string GT_DauTien(int vt)
        {
            string temp = "";
            for (int i = 0; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] != "?")
                    return _list[i][vt];
            }
            return temp;
        }
        string TanSuat_Max(int vt)
        {
            string temp = GT_DauTien(vt);
            int ts = TanSuat(vt, temp);
            for (int i = 0; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] != "?")
                {
                    int ts_n = TanSuat(i, vt, _list[i][vt]);

                    if (ts_n > ts)
                    {
                        temp = _list[i][vt];
                        ts = ts_n;
                    }
                }
            }
            return temp;
        }

        string TrungBinh(int vt)
        {
            string temp = "";
            double dou = 0;
            for (int i = 0; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] != "?")
                    dou += Convert.ToDouble(_list[i][vt]);
            }
            temp = (dou / _list.Count).ToString();
            return temp;
        }

        void Search_GiaTriDaiDien()
        {
            _GiaTriDaiDien = new List<string>();
            for (int i = 0; i < _SoThuocTinh; i++)
            {
                if (_LoaiThuocTinh[i] == "nominal")
                {
                    _GiaTriDaiDien.Add(TanSuat_Max(i));
                }
                if (_LoaiThuocTinh[i] == "numeric")
                {
                    _GiaTriDaiDien.Add(TrungBinh(i));
                }
            }
        }

        void MinMax(int vt)
        {
            if (_LoaiThuocTinh[vt] == "numeric")
            {
                double tempMin = Convert.ToDouble(_list[0][vt]);
                double tempMax = Convert.ToDouble(_list[0][vt]);
                for (int i = 0; i < _SoLuongMau; i++)
                {
                    if (_list[i][vt] != "?")
                    {
                        double temp = Convert.ToDouble(_list[i][vt]);
                        if (temp > tempMax)
                            tempMax = temp;
                        if (tempMax < tempMin)
                            tempMin = temp;
                    }
                }
                Min.Add(tempMin.ToString());
                Max.Add(tempMax.ToString());
            }
            else 
            {
                Min.Add(null);
                Max.Add(null);
            }
            
        }

        void MinMax()
        { 
            _Min = new List<string>();
            _Max = new List<string>();
            for (int i = 0; i < nThuocTinh; i++)
            {
                MinMax(i);
            }
        }

        void Replace()
        {
            for (int i = 0; i < _SoThuocTinh; i++)
            {
                Replace(i);
            }
        }

        void Replace(int vt)
        {
            for (int i = 0; i < _SoLuongMau; i++)
            {
                if (_list[i][vt] == "?")
                    _list[i][vt] = _GiaTriDaiDien[vt];
            }
        }

        Boolean KiemTraGiaTriPhanBiet(string temp,List<string> danhsach)
        {
            if (danhsach == null)
                return true;
            for (int i = 0; i < danhsach.Count; i++)
            {
                if (temp == danhsach[i])
                    return false;
            }
            return true;
        }
        void DemGiaTri()
        {
            _SoMauPhanBiet = new List<int>();
            _SoMauThieu = new List<int>();
            _GiaTriPhanBiet = new List<List<string>>();
            for (int i = 0; i < _SoThuocTinh; i++)
            {
                _SoMauPhanBiet.Add(0);
                _SoMauThieu.Add(0);
                List<string> danhsach = new List<string>();
                for (int j = 0; j < _SoLuongMau; j++)
                {
                    if (_list[j][i] == "?")
                    {
                        _SoMauThieu[i]++;
                    }
                    else
                    {
                        if (KiemTraGiaTriPhanBiet(_list[j][i],danhsach))
                        {
                            danhsach.Add(_list[j][i]);                            
                        }
                    }
                }
                _GiaTriPhanBiet.Add(danhsach);
                _SoMauPhanBiet[i] = danhsach.Count;
            }
        }
        public void ReadCSV(string url)
        {
            Read_ThuocTinh(url);
            Read_LoaiThuocTinh(url);
            Read_Data(url);
            Search_GiaTriDaiDien();
            DemGiaTri();
            MinMax();
        }

        public void Xuat()
        {
            for (int i = 0; i < _SoLuongMau; i++)
            {
                for (int j = 0; j < _SoThuocTinh; j++)
                {
                    Console.Out.Write(_list[i][j] + " ");
                }
                Console.Out.Write("\n");
            }
        }
          
    }
}
